package com.syerit.modules.utils
{
	import __AS3__.vec.Vector;
	
	import beherit.fl.transitions.utils.ITransitionManager;
	import beherit.fl.transitions.utils.TransitionEvent;
	import beherit.fx.modules.utils.IModuleComponent;
	
	import flash.display.DisplayObject;
	
	import mx.collections.ArrayCollection;
	import mx.containers.Canvas;
	import mx.containers.ViewStack;
	import mx.events.ModuleEvent;
	import mx.modules.IModuleInfo;
	import mx.modules.ModuleManager;
	
	
	public class ModuleViewStackManager extends ViewStack 
	{
		public var dataProvider:ArrayCollection;
		public var transitionManager:ITransitionManager;
		
		private var moduleInfoData:Vector.<IModuleInfo>;
		private var moduleComponentData:Vector.<IModuleComponent>;
		private var currentModuleIndex:int=-1;
		private var moduleCheckValue:int=0;
		
		public function ModuleViewStackManager()
		{
			super();
		}
		public function activate():void
		{
			trace(dataProvider);
			for(var i:int=0;i<dataProvider.length;i++)
			{
				addChild(new Canvas());
			}
			moduleInfoData = new Vector.<IModuleInfo>(dataProvider.length);
			moduleComponentData = new Vector.<IModuleComponent>(dataProvider.length);
		}
		public function changeModule(i:int):void
		{
			//if selected module != current module
			if(i!=currentModuleIndex)
			{
				this.visible=false;
				transitionManager.addEventListener(TransitionEvent.FINISHED,onTransitionsFinished);
				transitionManager.showLoader();

				//if this is not first show -> remove current Module
				if(currentModuleIndex!=-1)
				{
					transitionManager.outgoingDisplayObject=moduleComponentData[currentModuleIndex];
					removeCurrentModule(currentModuleIndex);
				}
				else
				{
					//pass empty disply object as no module has been loaded yet
					transitionManager.outgoingDisplayObject=this;
				}
				
				//if new moduleInfo reference doesn't exist yet -> load New Module
				if(moduleInfoData[i]==null)
				{
					loadNewModule(i);
				}
				//if new moduleInfo already exist (is non-relodable) -> activate new Module
				else
				{
					activateModule(moduleComponentData[i]);
				}
				
				
				currentModuleIndex = i;
				this.selectedIndex = currentModuleIndex;
			}
		}
		//############# NEW MODULE ##################
		private function loadNewModule(i:int):void
        {
        	var module:IModuleInfo = ModuleManager.getModule(dataProvider[i]+"?rand="+(100*Math.random()));
            module.addEventListener(ModuleEvent.READY, onModuleReady);
            moduleInfoData[i]=module;
            //setNewModule(modules[i]);
            module.load();
        }
        private function onModuleReady(e:ModuleEvent):void
		{
			var moduleCom:IModuleComponent = moduleInfoData[currentModuleIndex].factory.create() as IModuleComponent;
			moduleComponentData[currentModuleIndex]=moduleCom;
			Canvas(getChildAt(currentModuleIndex)).addChild(moduleCom as DisplayObject);
			//moduleCom.modelProxy = null;
			//module.serviceProxy = serviceProxy;
			moduleCom.addEventListener(ModulePageEvent.CONTENT_LOADED,onContentLoaded);
			moduleCom.loadAppData();
			moduleComponentData[currentModuleIndex].addEventListener(ModulePageEvent.CREATION_COMPLETE,onModuleCreationComplete);
		}
		private function onModuleCreationComplete(e:ModulePageEvent):void
		{
			//must be here because othervise can't see rendered content
			
			moduleCheck()
		}
		private function onContentLoaded(e:ModulePageEvent):void
		{
			trace("com.modules.utils.ModulePageManager: ModulePage content ready");
			
			moduleCheck()
		}
		private function moduleCheck():void
		{
			moduleCheckValue++;
			if(moduleCheckValue==2)
			{
				moduleCheckValue=0;
				moduleComponentData[currentModuleIndex].preactivate();
				activateModule(moduleComponentData[currentModuleIndex]);
			}
		}
		private function activateModule(module:IModuleComponent):void
		{
			transitionManager.ongoingDisplayObject= module;
			transitionManager.hideLoaderAndChange();
			//module.activate();
			//this.visible=true;
		}
        
        //############# CURRENT MODULE ##################
        private function removeCurrentModule(i:int):void
        {
        	if(IModuleComponent(Canvas(getChildAt(i)).getChildAt(0)).reloadable==true)
        	{
        		unloadCurrentModule(i);
        	}
        	else
        	{
        		hideCurrentModule(i);
        	}
        } 
        private function unloadCurrentModule(i:int):void
        {
        	moduleComponentData[i].destroy();
        	Canvas(getChildAt(i)).removeChildAt(0);
        	moduleInfoData[i].unload();
        	moduleInfoData[i].removeEventListener(ModuleEvent.READY, onModuleReady);
        	moduleInfoData[i]=null;
        }
        private function hideCurrentModule(i:int):void
        {
        	moduleComponentData[i].deactivate();
        }
        //############# OTHER ##################
		private function onTransitionsFinished(e:TransitionEvent):void
		{
			trace("fkjaslsdkjdlskjdlsakdjsalkdjsaldkajlsd");
			this.visible=true;
			transitionManager.removeEventListener(TransitionEvent.FINISHED,onTransitionsFinished);
			moduleComponentData[currentModuleIndex].activate();
			
		}
		private function onModuleUnloaded(e:ModuleEvent):void
		{
			//moduleLoader.removeEventListener(ModuleEvent.READY,onModuleReady);
			//moduleLoader.removeEventListener(ModuleEvent.UNLOAD,onModuleUnloaded);
		}
	}
}